"""
摄像头管理模块
负责摄像头的初始化、视频流获取和释放
"""

import cv2
import threading
import time
from typing import Optional, Tuple, Callable
import logging

class CameraManager:
    """摄像头管理器"""
    
    def __init__(self, camera_id: int = 0, width: int = 640, height: int = 480):
        """
        初始化摄像头管理器
        
        Args:
            camera_id: 摄像头ID，默认0（内置摄像头）
            width: 视频宽度
            height: 视频高度
        """
        self.camera_id = camera_id
        self.width = width
        self.height = height
        self.cap: Optional[cv2.VideoCapture] = None
        self.is_running = False
        self.current_frame = None
        self.frame_lock = threading.Lock()
        self.capture_thread: Optional[threading.Thread] = None
        self.frame_callback: Optional[Callable] = None
        
        # 设置日志
        self.logger = logging.getLogger(__name__)
        
    def initialize(self) -> bool:
        """
        初始化摄像头
        
        Returns:
            bool: 初始化是否成功
        """
        try:
            self.cap = cv2.VideoCapture(self.camera_id)
            if not self.cap.isOpened():
                self.logger.error(f"无法打开摄像头 {self.camera_id}")
                return False
            
            # 设置摄像头参数
            self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, self.width)
            self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, self.height)
            self.cap.set(cv2.CAP_PROP_FPS, 30)
            
            # 获取实际设置的参数
            actual_width = int(self.cap.get(cv2.CAP_PROP_FRAME_WIDTH))
            actual_height = int(self.cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
            actual_fps = self.cap.get(cv2.CAP_PROP_FPS)
            
            self.logger.info(f"摄像头初始化成功: {actual_width}x{actual_height} @ {actual_fps}fps")
            
            return True
            
        except Exception as e:
            self.logger.error(f"摄像头初始化失败: {e}")
            return False
    
    def start_capture(self, frame_callback: Optional[Callable] = None) -> bool:
        """
        开始视频捕获
        
        Args:
            frame_callback: 帧回调函数，接收每一帧图像
            
        Returns:
            bool: 启动是否成功
        """
        if not self.cap or not self.cap.isOpened():
            self.logger.error("摄像头未初始化")
            return False
        
        if self.is_running:
            self.logger.warning("摄像头已在运行中")
            return True
        
        self.frame_callback = frame_callback
        self.is_running = True
        
        # 启动捕获线程
        self.capture_thread = threading.Thread(target=self._capture_loop, daemon=True)
        self.capture_thread.start()
        
        self.logger.info("摄像头捕获已启动")
        return True
    
    def _capture_loop(self):
        """摄像头捕获循环"""
        while self.is_running:
            try:
                ret, frame = self.cap.read()
                if not ret:
                    self.logger.warning("无法读取摄像头帧")
                    time.sleep(0.1)
                    continue
                
                # 更新当前帧
                with self.frame_lock:
                    self.current_frame = frame.copy()
                
                # 调用回调函数
                if self.frame_callback:
                    self.frame_callback(frame)
                
                # 控制帧率
                time.sleep(1/30)  # 30fps
                
            except Exception as e:
                self.logger.error(f"摄像头捕获错误: {e}")
                time.sleep(0.1)
    
    def get_current_frame(self) -> Optional[Tuple[bool, any]]:
        """
        获取当前帧
        
        Returns:
            Tuple[bool, frame]: (是否成功, 帧数据)
        """
        with self.frame_lock:
            if self.current_frame is not None:
                return True, self.current_frame.copy()
            return False, None
    
    def stop_capture(self):
        """停止视频捕获"""
        if not self.is_running:
            return
        
        self.is_running = False
        
        # 等待捕获线程结束
        if self.capture_thread and self.capture_thread.is_alive():
            self.capture_thread.join(timeout=2.0)
        
        self.logger.info("摄像头捕获已停止")
    
    def release(self):
        """释放摄像头资源"""
        self.stop_capture()
        
        if self.cap:
            self.cap.release()
            self.cap = None
        
        self.logger.info("摄像头资源已释放")
    
    def get_camera_info(self) -> dict:
        """
        获取摄像头信息
        
        Returns:
            dict: 摄像头信息
        """
        if not self.cap or not self.cap.isOpened():
            return {}
        
        return {
            'width': int(self.cap.get(cv2.CAP_PROP_FRAME_WIDTH)),
            'height': int(self.cap.get(cv2.CAP_PROP_FRAME_HEIGHT)),
            'fps': self.cap.get(cv2.CAP_PROP_FPS),
            'brightness': self.cap.get(cv2.CAP_PROP_BRIGHTNESS),
            'contrast': self.cap.get(cv2.CAP_PROP_CONTRAST),
            'saturation': self.cap.get(cv2.CAP_PROP_SATURATION),
        }
    
    def set_camera_property(self, prop: int, value: float) -> bool:
        """
        设置摄像头属性
        
        Args:
            prop: OpenCV属性常量
            value: 属性值
            
        Returns:
            bool: 设置是否成功
        """
        if not self.cap or not self.cap.isOpened():
            return False
        
        try:
            result = self.cap.set(prop, value)
            if result:
                self.logger.info(f"摄像头属性设置成功: {prop} = {value}")
            else:
                self.logger.warning(f"摄像头属性设置失败: {prop} = {value}")
            return result
        except Exception as e:
            self.logger.error(f"设置摄像头属性时出错: {e}")
            return False
    
    def __del__(self):
        """析构函数"""
        self.release()